Crate cynic[−][src]
Expand description
Cynic
Cynic is a GraphQL query builder & data mapper for Rust.
This documentation is primarily intended to be a reference for specific functions,
for a guide to using Cynic
see the website: cynic-rs.dev.
Overview
To get started with Cynic you’ll need a GraphQL schema for the API you wish to query. The examples will be using the star wars API.
Generating a Query DSL
Once you’ve got your schema installed locally, you’ll need to use the
use_schema
macro to generate a schema module:
mod schema {
cynic::use_schema!("../schemas/starwars.schema.graphql");
}
This macro generates a few things:
- Some structs to represent the Input types the underlying schema. You may need to use these to build mutations or as parameters to queries.
- Definitons of all the Enums in the provided schema. You’ll need these if you want to use any enum types.
- Type safe selection set functions. These can be used to build up a query
manually, though it’s usually easier to use the
QueryFragment
derive functionality explained below. Hopefully you’ll not need to use these directly too often.
Though using macros to generate these is convenient, it does leave a lot of code
to the imagination. You can get a glimpse of the things this defines by running
cargo doc --document-private-items
and having a look in the schema
module.
It’s not ideal, but at least provides some visibility into the various enum types.
Creating QueryFragments
Now that you have a schema defined, you can start building some queries.
Cynic lets you do this by deriving QueryFragment
for a struct. For example,
if we wanted to know what director title & director a Star Wars film had, we
could define this QueryFragment
:
#[derive(cynic::QueryFragment)]
#[cynic(schema_path = "../schemas/starwars.schema.graphql")]
struct Film {
title: Option<String>,
director: Option<String>
}
// This `Film` struct can now be used as the type of a field on any other
// `QueryFragment` struct and cynic will know how to turn that into a GraphQL
// query, and populate the `Film` struct from the response.
// For example, if we wanted to know the Director for a particular film:
#[derive(cynic::QueryFragment)]
#[cynic(
schema_path = "../schemas/starwars.schema.graphql",
graphql_type = "Root"
)]
struct FilmDirectorQuery {
// Here we use the `#[arguments()]` attribute on the `film` field to provide a
// hard coded film ID to look up. Though useful for demonstration, hard coded
// arguments like this aren't much use in reality. For more details on providing
// runtime arguments please see below.
#[arguments(id = cynic::Id::new("ZmlsbXM6MQ=="))]
film: Option<Film>,
}
// You can then build a `cynic::Operation` from this fragment
use cynic::{QueryBuilder};
let operation = FilmDirectorQuery::build(());
operation
above implements serde::Serialize
so can be used with any HTTP
client. A selection of HTTP client integrations are provided in
cynic::http
- see the docs there for examples of using a cynic::Operation
let response = reqwest::blocking::Client::new()
.post("a_url")
.json(&operation)
.send()?;
let result = query.decode_response(response.json()?)?;
After this code has run, result will be an instance of FilmDirectorQuery
with the film populated appropriately.
Dynamic Query Arguments
The query above was useful for demonstration, but you’ll usually want to be able to provide parameters to your query. To do this, you should define a struct that contains all of the parameters you want to provide:
// Deriving `FragmentArguments` allows this struct to be used as arguments to a
// `QueryFragment` fragment, whether it represents part of a query or a whole query.
#[derive(cynic::FragmentArguments)]
struct FilmArguments {
id: Option<cynic::Id>
}
// You can now define a query to use these arguments on. For example, to make
// `FilmDirectorQuery` a bit more dynamic:
#[derive(cynic::QueryFragment)]
#[cynic(
schema_path = "../schemas/starwars.schema.graphql",
graphql_type = "Root",
// By adding the `argument_struct` parameter to our `QueryFragment` we've made a variable
// named `args` avaiable for use in the `arguments` attribute.
argument_struct = "FilmArguments"
)]
struct FilmDirectorQueryWithArgs {
// Here we use `args`, which we've declared above to be an instance of `FilmArguments`
#[arguments(id = &args.id)]
film: Option<Film>,
}
// Then we can build a query using this new struct;
use cynic::QueryBuilder;
let operation = FilmDirectorQueryWithArgs::build(
FilmArguments{ id: Some("ZmlsbXM6MQ==".into()) }
);
Feature Flags
Cynic has a few features that are controlled by feature flags.
surf
adds integration with thesurf
http client.rewest
adds async integration with thereqwest
http client.rewest-blocking
adds blocking integration with thereqwest
http client.
It’s worth noting that each of these features pulls in extra
dependencies, which may impact your build size. Particularly
if you’re targetting WASM. In particular the url
crate has
known issues when
targetting web assembly.
Re-exports
Modules
HTTP client support for cynic.
GraphQL has a lot of input coercion rules.
SelectionSet
s are the core building block of GraphQL queries in cynic.
Macros
Defines common InputType
impls for a given type & type lock.
Implements [cynic::Scalar
] for a given type & type lock.
Imports a schema for use by cynic.
Structs
A single argument to a graphql operation.
Context passed into a QueryFragment/InlineFragments
A model describing an error which has taken place during execution.
The response to a GraphQl operation
A GraphQL ID
An Operation that can be sent to a remote GraphQL server.
A StreamingOperation is an Operation that expects a stream of results.
Enums
Traits
A trait for GraphQL enums.
A marker trait for the arguments types on QueryFragments.
Used for converting between different argument types in a QueryFragment hierarchy.
Indicates that a type may be used to select one or more members of an interface/union type.
A trait for GraphQL input objects.
Provides a build
function on QueryFragment
s that represent a mutation
A marker trait that indicates a particular type is at the root of a GraphQL schemas mutation hierarchy.
Provides a build
function on QueryFragment
s that represent a query
Indicates that a type may be used as part of a graphql query.
A marker trait that indicates a particular type is at the root of a GraphQL schemas query hierarchy.
Indicates that a type can be used as a scalar of TypeLock
in a graphql query
Provides a build
function on QueryFragment
s that represent a subscription
A marker trait that indicates a particular type is at the root of a GraphQL schemas subscription hierarchy.
Attribute Macros
An attribute macro to automatically add schema attributes to cynic derives.
Derive Macros
Derives cynic::Enum
Derives cynic::FragmentArguments
Derives cynic::InlineFragments
Derives InputObject
Derives cynic::QueryFragment
Derives cynic::Scalar